<?php

require_once( 'flexical/model/feed.php' );
require_once( 'flexical/model/query.php' );
require_once( 'flexical/model/feed-query.php' );
require_once( 'flexical/model/format.php' );
require_once( 'flexical/model/listing.php' );

require_once( 'flexical/service/cao.php' );
require_once( 'flexical/service/cao-factory.php' );
require_once( 'flexical/service/dao.php' );

class Flexical_Service_Report_Generator
{
	private $cao = null;

	private $dao = null;

	public function __construct()
	{
		$this->cao = Flexical_Service_CAO_Factory::get_cao();
		$this->dao = new Flexical_Service_DAO();
	}

	public function generate( $listing )
	{
		return $this->format_events( $listing, $this->get_events( $listing ) );
	}

	private static function sort_events_ascending( $a, $b )
	{
		if ( $a->start_date == $b->start_date )
		{
			return 0;
		}

		else
		{
			return $a->start_date < $b->start_date ? -1 : 1;
		}
	}

	private static function sort_events_descending( $a, $b )
	{
		if ( $a->start_date == $b->start_date )
		{
			return 0;
		}

		else
		{
			return $b->start_date < $a->start_date ? -1 : 1;
		}
	}

	private function get_events( $listing )
	{
		$events = array();

		foreach ( $listing->feed_query_list as $feed_query )
		{
			$feed = $this->dao->read_feed( $feed_query->feed_id );
			$query = $this->dao->read_query( $feed_query->query_id );

			foreach ( $this->cao->read_events( $feed, $query ) as $event )
			{
				$events[] = $event;
			}
		}
		
		usort( $events, 'Flexical_Service_Report_Generator::sort_events_ascending' );

		if ( $listing->max_number_of_events > 0 )
		{
			while ( sizeof( $events ) > $listing->max_number_of_events )
			{
				array_pop( $events );
			}
		}

		switch ( $listing->sort_order )
		{
			case 'ascending':
				usort( $events, 'Flexical_Service_Report_Generator::sort_events_ascending' );
				break;

			case 'descending':
				usort( $events, 'Flexical_Service_Report_Generator::sort_events_descending' );
				break;

			default:
				throw new Exception( "Invalid sort order: " . $listing->sort_order );
		}

		return $events;
	}

	private function format_events( $listing, $events )
	{
		$format = $this->dao->read_format( $listing->format_id );

		$report = '';

		$report .= $this->format_header_footer( $listing, $format->start_listing_code );

		if ( sizeof( $events ) > 0 )
		{
			foreach ( $events as $event )
			{
				$report .= $this->format_event( $listing, $format, $event );
			}
		}

		$report .= $this->format_header_footer( $listing, $format->end_listing_code );

		return $report;
	}

	private function format_header_footer( $listing, $text )
	{
		$result = $text;

		$result = str_replace( '${listing_title}', $event->listing->title, $result );

		return $result;
	}

	private function format_event( $listing, $format, $event )
	{
		date_default_timezone_set( $event->timezone );

		$result = $format->event_code;

		$map_url = 'http://maps.google.com/?q=' . str_replace( ' ', '+', $event->location );

		$result = str_replace( '${title}', $event->title, $result );
		$result = str_replace( '${description}', $event->description, $result );
		$result = str_replace( '${location}', $event->location, $result );
		$result = str_replace( '${start_date}', date( $format->date_format, $event->start_date ), $result);
		$result = str_replace( '${end_date}', date( $format->date_format, $event->end_date ), $result);
		$result = str_replace( '${start_time}', $event->all_day_event ? '' : date( $format->time_format, $event->start_date ), $result);
		$result = str_replace( '${end_time}', $event->all_day_event ? '' : date( $format->time_format, $event->end_date ), $result);
		$result = str_replace( '${time_separator}', $event->all_day_event ? '' : '-', $result );
		$result = str_replace( '${map_url}', $map_url, $result);
		$result = str_replace( '${feed_title}', $event->feed->title, $result );
		$result = str_replace( '${query_title}', $event->query->title, $result );
		$result = str_replace( '${listing_title}', $event->listing->title, $result );

		$matches = array();
		while ( preg_match( '/\${start:([^}]*)}/', $result, $matches ) )
		{
			$result = preg_replace( '/\${start:' . $matches[ 1 ] . '}/', date( $matches[ 1 ], $event->start_date ), $result );
		}

		return htmlspecialchars_decode( $result );
	}
}

?>
